package com.sam.lt.restful;

import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.Gson;
import com.sam.lt.entity.NodeData;
import com.sam.lt.service.NodeDataService;
import com.sam.lt.service.NodeService;
import com.sam.lt.vo.RetMsg;
import com.sam.lt.vo.TreeNodeDataVo;
import com.sam.lt.vo.TreeNodeVo;

@RestController
@RequestMapping("/tree")
public class LittleTreeController {
	private final Logger logger = LogManager.getLogger(this.getClass());
	
	@Autowired
	NodeService nodeService;
	
	@Autowired
	NodeDataService nodeDataService;
	
	@RequestMapping(value = "/view", produces = "application/json")
	public Object view(@RequestParam(value="name", defaultValue="t0") String name) {
		TreeNodeVo tree = nodeService.getTreeByName(name);
		if(tree == null)
			return "{}";
		return tree;
	}
	
	/**
	 * view the tree or branch without node data
	 * @param nodeId
	 * @return
	 */
	@RequestMapping(value = "/branch", produces = "application/json")
	public Object branch(@RequestParam(value="nodeId") Integer nodeId) {
		TreeNodeVo tree = nodeService.viewTree(nodeId);
		if(tree == null)
			return "{}";
		return tree;
	}
	
	/**
	 * view the tree or branch with node data
	 * @param nodeId
	 * @return
	 */
	@RequestMapping(value = "/fillUpTree", produces = "application/json")
	public Object fillUpTree(@RequestParam(value="name") String name,
			@RequestParam(value="level", defaultValue="999") Integer level ) {
		
		TreeNodeVo tree = nodeService.getTreeByName(name,level);
		nodeDataService.hangUpTree(tree);
		if(tree == null)
			return "{}";
		return tree;
	}
	
	/**
	 * view the tree or branch with node data
	 * @param nodeId
	 * @return
	 */
	@RequestMapping(value = "/treeBranch", produces = "application/json")
	public Object treeBranch(@RequestParam(value="nodeId") Integer nodeId) {
		TreeNodeVo tree = nodeService.viewTree(nodeId);
		nodeDataService.hangUpTree(tree);
		if(tree == null)
			return "{}";
		return tree;
	}
	
	@RequestMapping(value = "/createNode", produces = "application/json")
	public Object createNode(@RequestParam(value="value") String value,
			@RequestParam(value="parent") Long parent) {
		
		return null;
	}
	
	@PostMapping("update")
	public Object update(@RequestBody String data) {
		try {
			String json = java.net.URLDecoder.decode(data,"UTF-8");
		
			logger.info("update data:{}",json);
			TreeNodeVo vo = new Gson().fromJson(json, TreeNodeVo.class);
			if(vo == null)
				return RetMsg.getResult(RetMsg.ERROR);
		
			logger.info("start to update tree:{}",vo.getValue());
			nodeService.updateOrCreateTree(vo);
			logger.info("finished update tree:{}",vo.getValue());
		}
		catch(Throwable e) {
			logger.error("update tree error:",e);
			RetMsg.getResult(RetMsg.ERROR);
		}
		
		return RetMsg.getResult(RetMsg.SUCCESS);
	}
	
	/**
	 * save or update node data
	 * @param data
	 * @return
	 */
	@PostMapping("nodeData")
	public Object nodeData(@RequestBody String data) {
		try {
			String json = java.net.URLDecoder.decode(data,"UTF-8");
			logger.info("start to save data:{}",json);
			TreeNodeDataVo vo = new Gson().fromJson(json, TreeNodeDataVo.class);
			List<NodeData> nodeDataList = vo.spliteToNodeData();
			nodeDataService.batchSaveOrUpdate(vo.getNodeId(),nodeDataList);
			logger.info("finished data:{}",vo);
		} catch (UnsupportedEncodingException e) {
			logger.error("nodeInfo error:",e);
			RetMsg.getResult(RetMsg.ERROR);
		}
		
		return RetMsg.getResult(RetMsg.SUCCESS);
	}
	
	@PostMapping("getNodeData")
	public Object getNodeData(@RequestParam(value="nodeId") Integer nodeId) {
		logger.info("getNodeData:{}",nodeId);
		TreeNodeDataVo vo = nodeDataService.getNodeData(nodeId);
		logger.info("finished data:{}",vo);
		if(vo == null)
			return "{}";
		
		return vo;
	}
	
	@PostMapping("test")
	public Object test(@RequestBody String data) {
		try {
			System.out.println(java.net.URLDecoder.decode(data,"UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return RetMsg.getResult(RetMsg.SUCCESS);
	}
	
	@RequestMapping(value = "/title")
	public Object title() {
		return "英语学院";
	}
}
